package com.stock.service;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.stock.model.ImageResponse;

@Service
public class StockService {
    
    @Value("${image.up.path}")
    private String upPath;
    
    @Value("${image.down.path}")
    private String downPath;

    // 添加历史记录缓存
    private final Map<String, Deque<ImageResponse>> userHistory = new ConcurrentHashMap<>();
    private final int MAX_HISTORY = 50; // 最大历史记录数

    /**
     * 保存上传的文件
     */
    public List<String> saveUploadedFiles(MultipartFile[] files, String type) {
        // 参数验证
        if (files == null || files.length == 0) {
            throw new IllegalArgumentException("No files provided");
        }
        if (!("UP".equals(type) || "DOWN".equals(type))) {
            throw new IllegalArgumentException("Invalid type: " + type);
        }

        List<String> savedFiles = new ArrayList<>();
        String basePath = "UP".equals(type) ? upPath : downPath;

        try {
            // 确保目录存在
            Files.createDirectories(Paths.get(basePath));

            for (MultipartFile file : files) {
                if (file.isEmpty()) continue;

                // 验证文件类型
                String contentType = file.getContentType();
                if (contentType == null || !contentType.startsWith("image/")) {
                    continue;
                }

                // 生成文件名
                String fileName = generateTimeStampFileName(file.getOriginalFilename());
                Path targetPath = Paths.get(basePath).resolve(fileName);

                // 保存文件
                Files.copy(file.getInputStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
                savedFiles.add(type + "/" + fileName);
            }

            return savedFiles;
        } catch (IOException e) {
            throw new RuntimeException("Failed to store files", e);
        }
    }

    /**
     * 获取随机图片，并记录到历史
     */
    public ImageResponse getRandomImage(String sessionId) {
        ImageResponse image = getRandomImageInternal();
        
        // 获取或创建用户的历史记录
        Deque<ImageResponse> history = userHistory.computeIfAbsent(sessionId, 
            k -> new LinkedList<>());
        
        // 添加到历史记录
        history.addLast(image);
        if (history.size() > MAX_HISTORY) {
            history.removeFirst();
        }
        
        return image;
    }

    /**
     * 获取上一张图片
     */
    public ImageResponse getPreviousImage(String sessionId) {
        Deque<ImageResponse> history = userHistory.get(sessionId);
        if (history == null || history.size() < 2) {
            return null;
        }
        
        // 移除当前图片
        history.removeLast();
        // 返回上一张图片
        return history.getLast();
    }

    /**
     * 获取下一张图片
     */
    public ImageResponse getNextImage(String sessionId) {
        return getRandomImage(sessionId);
    }

    /**
     * 加载图片资源
     */
    public Resource loadImageAsResource(String type, String filename) {
        try {
            String basePath = "UP".equals(type.toUpperCase()) ? upPath : downPath;
            Path filePath = Paths.get(basePath).resolve(filename);
            
            if (!Files.exists(filePath)) {
                throw new RuntimeException("File not found: " + type + "/" + filename);
            }
            
            return new UrlResource(filePath.toUri());
        } catch (MalformedURLException ex) {
            throw new RuntimeException("File not found: " + type + "/" + filename, ex);
        }
    }

    /**
     * 生成时间戳文件名
     */
    private String generateTimeStampFileName(String originalFilename) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss_SSS");
        String timestamp = sdf.format(new Date());
        String extension = getFileExtension(originalFilename);
        return timestamp + "_" + System.nanoTime() % 1000 + extension;
    }

    private String getFileExtension(String filename) {
        if (filename == null) {
            return ".jpg";
        }
        int lastDotIndex = filename.lastIndexOf(".");
        if (lastDotIndex == -1) {
            return ".jpg";
        }
        return filename.substring(lastDotIndex).toLowerCase();
    }

    private boolean isImageFile(String filename) {
        return filename.toLowerCase().matches(".*\\.(jpg|jpeg|png)$");
    }

    // 原来的 getRandomImage 改名为 getRandomImageInternal
    private ImageResponse getRandomImageInternal() {
        try {
            // 随机选择目录
            String type = new Random().nextBoolean() ? "UP" : "DOWN";
            Path basePath = Paths.get("UP".equals(type) ? upPath : downPath);

            if (!Files.exists(basePath)) {
                throw new RuntimeException("Image directory not found: " + basePath);
            }

            // 获取所有图片
            List<Path> images = Files.list(basePath)
                    .filter(path -> isImageFile(path.toString()))
                    .collect(Collectors.toList());

            if (images.isEmpty()) {
                throw new RuntimeException("No images found in " + type + " directory");
            }

            // 随机选择图片
            Path selectedImage = images.get(new Random().nextInt(images.size()));
            String filename = selectedImage.getFileName().toString();

            return new ImageResponse(type + "/" + filename, type, filename.substring(0, 8)); // 从文件名提取日期
        } catch (IOException e) {
            throw new RuntimeException("Error accessing image files", e);
        }
    }
} 